package com.yvon.boot.mybatis;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yvon.boot.mybatis.page.ListData;
import com.yvon.boot.mybatis.search.BaseQuery;
import com.yvon.boot.mybatis.search.PageQuery;
import org.springframework.util.Assert;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Objects;

/**
 * 基础 service实现类
 *
 * @author : Yvon
 * @since : 2021-09-03
 */
public class BaseServiceImpl<T, M extends BaseMapper<T>> extends ServiceImpl<M, T> implements IBaseService<T> {

    private static final String COLUMN_ID = "id";

    public BaseServiceImpl() {
    }

	@Override
	public <T> ListData<T> page(PageQuery pageQuery) {
		Page<T> page = (Page<T>) pageQuery.buildQuery(this.query()).page(pageQuery.buildPage());
		return ListData.restPage(page);
	}

	@Override
    public <D> ListData<D> page(PageQuery pageQuery, Class<D> dtoClass) {
        IPage<T> page = pageQuery.buildQuery(this.query()).page(pageQuery.buildPage());
        return ListData.restPage(page, dtoClass);
    }

    @Override
    public <D> List<D> list(BaseQuery baseQuery, Class<D> dtoClass) {
		QueryWrapper<T> queryWrapper = baseQuery.buildQuery(new QueryWrapper<>());
		return this.baseMapper.selectDtoList(queryWrapper, dtoClass);
	}


    @Override
    protected Class<T> currentModelClass() {
        ParameterizedType parameterizedType = (ParameterizedType)this.getClass().getGenericSuperclass();
        Type type = parameterizedType.getActualTypeArguments()[0];
        return (Class)type;
    }

    /**
     * 检查是否唯一
     * <p>
     *     新增时不传id，校验范围：全部内容 <br>
     *     更新时必传id，校验范围：除当前记录为的其他内容
     * </p>
     * <p>
     *     true ：唯一，不存在重复 <br>
     *     false：不唯一，存在重复
     * </p>
     *
     * @param column 列
     * @param value  值
     * @param id     ID
     * @return boolean
     * @author : Yvon / 2021-09-14
     */
    @Override
    public boolean isUniqueness(String column, Object value, Serializable id) {
        if (Objects.nonNull(value)) {
            QueryWrapper<T> wrapper = new QueryWrapper<>();
            wrapper.eq(column, value);
            wrapper.ne(Objects.nonNull(id), COLUMN_ID, id);
            return super.count(wrapper) == 0;
        }
        return true;

    }

    @Override
    public void checkUniqueness(String column, Object value, Serializable id, String message) {
        Assert.isTrue(isUniqueness(column, value, id), message);
    }

}
